﻿@page "/"
@using Microsoft.Agents.AI
@using System.Text.Json
@inject IServiceProvider ServiceProvider
@inject NavigationManager Nav
@inject AgentFx_AIWebChatApp_Persisting.Web.Services.ChatThreadStore ThreadStore
@implements IDisposable

<PageTitle>Chat</PageTitle>

<ChatHeader OnNewChat="@ResetConversationAsync" />

<ChatMessageList Messages="@messages" InProgressMessage="@currentResponseMessage">
    <NoMessagesContent>
        <div>To get started, try asking about these example documents. You can replace these with your own data and replace this message.</div>
        <ChatCitation File="Example_Emergency_Survival_Kit.pdf" />
        <ChatCitation File="Example_GPS_Watch.pdf" />
    </NoMessagesContent>
</ChatMessageList>

<div class="chat-container">
    <ChatSuggestions OnSelected="@AddUserMessageAsync" @ref="@chatSuggestions" />
    <ChatInput OnSend="@AddUserMessageAsync" @ref="@chatInput" />
    <SurveyPrompt />
</div>

@code {


    private readonly List<ChatMessage> messages = new();
    private CancellationTokenSource? currentResponseCancellation;
    private ChatMessage? currentResponseMessage;
    private ChatInput? chatInput;
    private ChatSuggestions? chatSuggestions;
    private AIAgent aiAgent = default!;
    private AgentThread thread = default!;

    protected override async Task OnInitializedAsync()
    {
        aiAgent = ServiceProvider.GetRequiredKeyedService<AIAgent>("ChatAgent");
        thread = await ThreadStore.LoadThreadAsync(aiAgent);
    }

    private async Task AddUserMessageAsync(ChatMessage userMessage)
    {
        CancelAnyCurrentResponse();
        messages.Add(userMessage); // show only new session messages
        chatSuggestions?.Clear();
        await chatInput!.FocusAsync();

        var responseText = new TextContent("");
        currentResponseMessage = new ChatMessage(ChatRole.Assistant, [responseText]);
        currentResponseCancellation = new();

        await foreach (var update in aiAgent.RunStreamingAsync(userMessage, thread, cancellationToken: currentResponseCancellation.Token))
        {
            responseText.Text += update.Text;
            ChatMessageItem.NotifyChanged(currentResponseMessage);
        }

        // Finalize assistant message into visible conversation
        messages.Add(currentResponseMessage!);
        currentResponseMessage = null;

        await PersistThreadAsync();
        chatSuggestions?.Update(messages);
    }

    private void CancelAnyCurrentResponse()
    {
        currentResponseCancellation?.Cancel();
        currentResponseMessage = null;
    }

    private async Task ResetConversationAsync()
    {
        CancelAnyCurrentResponse();
        ThreadStore.DeletePersistedThread();
        thread = aiAgent.GetNewThread();
        messages.Clear();
        await PersistThreadAsync();
        chatSuggestions?.Clear();
        await chatInput!.FocusAsync();
    }

    private Task PersistThreadAsync() => ThreadStore.SaveThreadAsync(thread);

    public void Dispose() => currentResponseCancellation?.Cancel();
}
